<!DOCTYPE html>
<html>
<head>
<script src='../../resources/testharness.js'></script>
<script src='../../resources/testharnessreport.js'></script>
</head>
<body>
<div id='testElement'>
  <div id='childTestElement'></div>
</div>
<style>
#testElement {
  font-size: 10px;
  --my-length: 10em;
  --my-inherited-length: 200px;
  --my-percentage: 10%;
  background-image: var(--my-image);
  width: var(--my-length);
  height: calc(var(--my-length) + var(--my-percentage) + 15px);
}
</style>
<script>
CSS.registerProperty(
{
  name: '--my-image',
  syntax: '<image>',
  inherits: false,
  initialValue: 'url()'
});
CSS.registerProperty(
{
  name: '--my-length',
  syntax: '<length>',
  inherits: false,
  initialValue: '0px'
});
CSS.registerProperty(
{
  name: '--my-inherited-length',
  syntax: '<length>',
  inherits: true,
  initialValue: '0px'
});
CSS.registerProperty(
{
  name: '--my-percentage',
  syntax: '<percentage>',
  inherits: false,
  initialValue: '0%'
});
CSS.registerProperty(
{
  name: '--my-unused-property',
  syntax: '<percentage>',
  inherits: false,
  initialValue: '0%'
});
// TODO(rjwright): Change this & put it in the CSS when relative URLs work with registered
// properties.
var locationPath = location.href.substring(0, location.href.lastIndexOf('/'));
var imagePath = locationPath + '/resources/1x1-green.png';
testElement.style = '--my-image: url(\"' + imagePath + '\");';

var computedStyleMap = testElement.computedStyleMap();
var childComputedStyleMap = childTestElement.computedStyleMap();

test(function() {
  assert_true(computedStyleMap.has('--my-length'));
  var result = computedStyleMap.get('--my-length');
  assert_equals(result.constructor.name, CSSUnitValue.name);
  assert_equals(result.toString(), '100px');
}, 'Getting a length type registered property returns a CSSUnitValue');

var t1 = async_test('Getting a URL image type registered property returns a CSSImageValue');
function t1Callback() {
  t1.step(function() {
    assert_true(computedStyleMap.has('--my-image'));
    var result = computedStyleMap.get('--my-image');
    assert_equals(result.constructor.name, CSSImageValue.name);
    assert_equals(result.toString(), 'url(\"' + imagePath + '\")');
  });
  t1.done();
}

test(function() {
  var result = computedStyleMap.get('width');
  assert_equals(result.constructor.name, CSSUnitValue.name);
  assert_equals(result.toString(), '100px');
}, 'Getting a width with a length type var value returns a CSSUnitValue');

var t2 = async_test('Getting a background-image with a URL image type var value returns a CSSImageValue');
function t2Callback() {
  t2.step(function() {
    var result = computedStyleMap.get('background-image');
    assert_equals(result.constructor.name, CSSImageValue.name);
    assert_equals(result.toString(), 'url(\"' + imagePath + '\")');
  });
  t2.done();
}

test(function() {
  assert_true(childComputedStyleMap.has('--my-inherited-length'));
  var result = childComputedStyleMap.get('--my-inherited-length');
  assert_equals(result.constructor.name, CSSUnitValue.name);
  assert_equals(result.toString(), '200px');
}, 'Getting an inherited length type registered property returns a CSSUnitValue');

test(function() {
  assert_true(childComputedStyleMap.has('--my-length'));
  result = childComputedStyleMap.get('--my-length');
  assert_equals(result.constructor.name, CSSUnitValue.name);
  assert_equals(result.toString(), '0px');
}, 'Getting a non-inherited length type registered property returns a CSSUnitValue');

test(function() {
  var result = computedStyleMap.get('height');
  assert_equals(result.constructor.name, CSSCalcValue.name);
  assert_equals(result.px, 115);
  assert_equals(result.percent, 10);
  assert_equals(result.toString(), 'calc(10% + 115px)');
}, 'Getting a height with a calc type containing var values returns a CSSCalcValue');

test(function() {
  assert_true(computedStyleMap.has('--my-unused-property'));
  result = computedStyleMap.get('--my-unused-property');
  assert_equals(result.constructor.name, CSSUnitValue.name);
  assert_equals(result.toString(), '0%');
}, 'Getting the value of a registered property that isn\'t set on the element ' +
    'returns the initial value for the property');

test(function() {
  assert_false(computedStyleMap.has('--my-non-property'));
  assert_equals(computedStyleMap.get('--my-non-property'), null);
}, 'Getting the value of a property that isn\'t registered returns null');

test(function() {
  var result = computedStyleMap.getAll('--my-length');
  assert_equals(result.length, 1);
  assert_equals(result[0].constructor.name, CSSUnitValue.name);
  assert_equals(result[0].toString(), '100px');
}, 'getAll for a length type registered property returns a single value');

test(function() {
  var result = Array.from(computedStyleMap)
                    .filter(m => m[0] == '--my-inherited-length')
                    .flat(2);
  assert_equals(result.length, 2);
  assert_equals(result[1].constructor.name, CSSUnitValue.name);
  assert_equals(result[1].toString(), '200px');
}, 'Inherited custom property produces correct type during iteration');

test(function() {
  var result = Array.from(computedStyleMap)
                    .filter(m => m[0] == '--my-length')
                    .flat(2);
  assert_equals(result.length, 2);
  assert_equals(result[1].constructor.name, CSSUnitValue.name);
  assert_equals(result[1].toString(), '100px');
}, 'Non-inherited custom property produces correct type during iteration');


document.onreadystatechange = function() {
  if(document.readyState == 'complete') {
    t1Callback();
    t2Callback();
  }
};

</script>
</body>
</html>
